﻿using ControlzEx.Theming;
using System;
using System.Collections;
using System.Linq;
using System.Windows;
using System.Windows.Media;
using Com.Lancetinc.Evs.Controls;
using Com.Lancetinc.Evs.Helpers;

namespace Com.Lancetinc.Evs
{
    public static class ThemeHelper
    {
        public static class Brushes
        {
            public static Lazy<Brush> AccentBase = new(() => GetBrush("MahApps.Brushes.AccentBase"));

            public static Lazy<Brush> ForegroundDisabled = new(() => GetBrush("MahApps.Brushes.IdealForegroundDisabled"));

            public static Lazy<Brush> MainWinBgDark = new(() => new SolidColorBrush(ColorHelper.ConvertFromString("#2f2e3e")));
        }

        public static Brush GetBrush(string key)
        {
            return (Brush)Application.Current.FindResource(key);
        }

        #region Theme

        #region CurrentTheme
        public static readonly DependencyProperty CurrentThemeProperty
            = DependencyProperty.RegisterAttached(
                "CurrentTheme",
                typeof(LevsTheme),
                typeof(ThemeHelper),
                new UIPropertyMetadata(LevsTheme.Light));

        public static LevsTheme GetCurrentTheme(UIElement element)
        {
            return (LevsTheme)element.GetValue(CurrentThemeProperty);
        }

        public static void SetCurrentTheme(UIElement element, LevsTheme value)
        {
            element.SetValue(CurrentThemeProperty, value);
        }

        #endregion

        private static ResourceDictionary _darkDefaultResource;
        private static ResourceDictionary _lightDefaultResource;

        /// <summary>
        /// 切换主题
        /// </summary>
        /// <param name="ele"></param>
        /// <param name="theme"></param>
        public static void ChangeTheme(FrameworkElement ele, LevsTheme theme)
        {
            switch (theme)
            {
                case LevsTheme.Light:
                    ChangeThemeToLight(ele);
                    break;
                case LevsTheme.Dark:
                    ChangeThemeToDark(ele);
                    break;
                default:
                    throw new ArgumentOutOfRangeException(nameof(theme), theme, null);
            }
        }

        /// <summary>
        /// 切换为深色主题
        /// </summary>
        /// <param name="ele"></param>
        public static void ChangeThemeToDark(FrameworkElement ele)
        {
            var darkTheme = ThemeManager.Current.Themes.FirstOrDefault(x => x.Name == "Dark.Navy");
            ThemeManager.Current.ChangeTheme(ele, darkTheme);
            if (_darkDefaultResource == null)
            {
                _darkDefaultResource = new ResourceDictionary { Source = new Uri("pack://application:,,,/Leinzett;component/Themes/Styles/Themes/Dark.Defaults.xaml") };
            }
            if (ele.Resources.MergedDictionaries.Contains(_darkDefaultResource))
                return;

            ele.Resources.BeginInit();
            if (_lightDefaultResource != null && ele.Resources.MergedDictionaries.Contains(_lightDefaultResource))
            {
                ele.Resources.MergedDictionaries.Remove(_lightDefaultResource);
            }
            ele.Resources.MergedDictionaries.Add(_darkDefaultResource);
            ele.Resources.EndInit();

            SetCurrentTheme(ele, LevsTheme.Dark);
            ApplyMyCtrlTheme(ele, LevsTheme.Dark);
        }

        public static void ChangeThemeToLight(FrameworkElement ele)
        {
            var lightTheme = ThemeManager.Current.Themes.FirstOrDefault(x => x.Name == "Light.Navy");
            ThemeManager.Current.ChangeTheme(ele, lightTheme);
            if (_lightDefaultResource == null)
            {
                _lightDefaultResource = new ResourceDictionary { Source = new Uri("pack://application:,,,/Leinzett;component/Themes/Styles/Themes/Light.Defaults.xaml") };
            }
            if (ele.Resources.MergedDictionaries.Contains(_lightDefaultResource))
                return;

            ele.Resources.BeginInit();
            if (_darkDefaultResource != null && ele.Resources.MergedDictionaries.Contains(_darkDefaultResource))
            {
                ele.Resources.MergedDictionaries.Remove(_darkDefaultResource);
            }
            ele.Resources.MergedDictionaries.Add(_lightDefaultResource);
            ele.Resources.EndInit();

            SetCurrentTheme(ele, LevsTheme.Light);
            ApplyMyCtrlTheme(ele, LevsTheme.Light);
        }

        private static void ApplyMyCtrlTheme(FrameworkElement ele, LevsTheme theme)
        {
            foreach (var myEle in WpfHelper.FindChildren(ele,
                         e => e is LevsCard or MainControlButton))
            {
                SetCurrentTheme(myEle, theme);
            }
        }

        private static void PrintResource(ResourceDictionary res, int indent = 0)
        {
            foreach (DictionaryEntry entry in res)
            {
                Console.WriteLine(new string('\t', indent) + entry.Key);
            }

            foreach (var dic in res.MergedDictionaries)
            {
                PrintResource(dic, indent + 1);
            }
        }
        #endregion
    }

    public enum LevsTheme
    {
        Light,
        Dark
    }
}

